
import json, os, sys, time, random, _thread

def _app_py(request_, response_, route_args_):
	with open('web/index_py.html') as fp:
		content = fp.read()
	app = route_args_['app'].strip()
	if app != '':
		content = content.replace("/web/main.py", f"/web/{app}.py")
	return response_.write_response_OK_(content_type_='text/html', content_=content, charset_='UTF-8')

def _app(request_, response_, route_args_):
	app = route_args_['app'].strip()
	if app=='':
		route_args_['app'], app = 'main', 'main'
	if os.path.isfile(f'web/{app}.py'):
		return _app_py(request_, response_, route_args_)
	return response_.write_response_error_(400, f'不存在 web/{app}.py')

rpc_registry = {}
def _handle_rpc(data):
	func_name = data['func_name']
	argv = data['argv']
	kwargs = data['kwargs']
	api_key = data['api_key']
	if func_name not in rpc_registry:
		return {'error': f'没有该服务: {func_name}'}
	if len(rpc_registry[func_name])==2:
		api_key_gt, func = rpc_registry[func_name]
		rpc_registry[func_name] = (api_key_gt, func, _thread.allocate_lock())
	api_key_gt, func, lock = rpc_registry[func_name]
	if api_key_gt is not None and api_key_gt!=api_key:
		return {'error': 'api_key' if api_key is None else f'错误的 API_KEY: {api_key}'}
	else:
		try:
			lock.acquire()
			res = func(*argv, **kwargs)
		finally:
			lock.release()
		return res

def _ajax(request_, response_, route_args_):
	global rpc_registry
	params_ = request_.params_
	assert 'data' in params_, '服务请求参数中缺少 data'
	data = json.loads(params_['data'])
	try:
		res = _handle_rpc(data)
	except Exception as ex:
		from serv.lib.http_ import http_handle_ex_
		res = {'error': http_handle_ex_(ex)}
	json_ = json.dumps(res)
	return response_.write_response_JSON_OK_(json_)

http_ = None
def _start_server(port_, max_threads_):
	from .lib.http_ import Http_
	global http_
	assert http_ is None
	http_ = Http_(ip_='0.0.0.0', port_=port_, web_path_='web', max_threads_=max_threads_)
	http_.add_route_('/ajax', _ajax, 'POST')
	http_.add_route_('/{app}', _app, 'GET')
	http_.add_route_('/{app}', _app, 'POST')
	http_.start_()

def _stop_server():
	http_.stop_()

# from . import css
# css.download_mdl_themes()

from web.py_lib.sudoku import Sudoku
from web.py_lib.problem import random_sukodu as random_sukodu_1
random_sukodu_repo = []
def gen_sukodu(size):
	print('正在生成题目', end=' ')
	sys.stdout.flush()
	while len(random_sukodu_repo)<size:
		res = random_sukodu_1(max_difficulty=0)
		for h,d in res:
			if len(h)==0:
				nz = sum([1 for i in range(9) for j in range(9) if d[i][j]>0])
				print(nz, end=' ')
				random_sukodu_repo.append(d)
		sys.stdout.flush()
	print()
repo_path = 'sukodu_repo.json'
if os.path.isfile(repo_path):
	with open(repo_path) as fp:
		random_sukodu_repo = json.load(fp)
else:
	gen_sukodu(10)
	with open(repo_path, 'w') as fp:
		json.dump(random_sukodu_repo, fp, indent='\t')
def random_sukodu():
	return random_sukodu_repo[random.randint(0,len(random_sukodu_repo)-1)]
rpc_registry['search'] = [None, Sudoku.search]
rpc_registry['random_sukodu'] = [None, random_sukodu]

port = int(sys.argv[1]) if len(sys.argv)>=2 else 8000

print(f'网页服务器端口: {port}')
_start_server(port, 100)
print('网页服务器已关闭')
